package chat;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.text.StyledDocument;

import voSetting.ChattingVO;
import voSetting.PortVO;
import voSetting.StateSetVO;

public class ChatServerThread extends Thread {
// <1. 필드요소>
	// 1-1. 
	ChatServer chatServer; 	// 1) ChatServer 객체 cc 선언
//	Chatting chatting;	// 2)
	
	Socket socket; 	// 3). Socket 객체 socket 선언
	// 1-2. 
	InputStream is;
	ObjectInputStream ois;

	OutputStream os;
	ObjectOutputStream oos;

// <2. 생성자> - 매개변수가 있는 생성자. 생성자는 실행시 값을 초기화한다.
	public ChatServerThread(ChatServer chatServer, Socket s) {
		this.chatServer = chatServer; 
		this.socket = s;
		start(); // start run
	}

// <3. run메소드> - 쓰레드를 상속 시, run 메소드가 있어야한다.
	public void run() {
		try { 
			os = socket.getOutputStream(); // 3-1. 
			oos = new ObjectOutputStream(os);
			is = socket.getInputStream();  
			ois = new ObjectInputStream(is); 
			System.out.println("서버스레드로 들어와서 와일문 전까지 들어왔소.");
			
// < 4. command 내용>
			while (true) { // 3-2. 계속해서 데이터를 받아오기 위해서 반복문을 쓴다.
				ChattingVO chattingVO = (ChattingVO) ois.readObject(); 
				//PortVO portVO = 
				switch (chattingVO.command) {
				case 1: // CONNECT : 로그인 내용을 처리한다.
					//chatting.dl_chatter.elements(); 
					//chatting.dl_chatter.addElement(chattingVO.m_id); 
					//chatting.dl_chatter.addElement(chattingVO.getE_name()); // 값을 넣고 뽑든가 하자. 
					//Enumeration<String> eum = chatting.dl_chatter.elements(); 
					//Enumeration<String> eum = chatServer.hash_chatter.keySet().
//					Vector<String> v = new Vector(); 
//					while (eum.hasMoreElements()) { 
//						String next = eum.nextElement();
//						v.add(next);
//						System.out.println(next + " 와일문도 돌고 있엄"); 
//					}
					chatServer.hash_chatter.put(chattingVO.getM_id(), this); 
					chatServer.hash_id_name.put(chattingVO.getM_id(), chattingVO.getE_name());
					
					chattingVO.setObj(name_setting());
					sendMsgAll(chattingVO);
					
					break;
				case 2: // disconnect : 연결종료된 내용을 처리한다. 
					
					chattingVO.setObj(name_setting());
					sendMsgAll(chattingVO); 
					System.out.println(chattingVO.getE_name()+"님이 나간다고 서버에 요청했슈");
					chatServer.hash_chatter.remove(chattingVO.getM_id()); // 4-15. 연결종료한 사람을 해쉬맵 clients에서 지운다.
					chatServer.hash_id_name.remove(chattingVO.getM_id());
					break;

				case 3: // message : 서버에 들어온 메시지를 처리한다.
					/*StyledDocument doc = chatting.textPane.getStyledDocument(); 
					doc.insertString(doc.getLength(), chattingVO.getM_id() + " : " + chattingVO.getMessage() + "\n", null); 
					chatting.textPane.setCaretPosition(doc.getLength()); */
					sendMsgAll(chattingVO); 
					break;
				case 4 : // 초대
					StateSetVO ssvo = new StateSetVO();
					ssvo.setVo_type(2);
					PortVO pvo = new PortVO();
					pvo.setCommand(1);
					pvo.setPort(chattingVO.getPort());
					ssvo.setVo(pvo);
					
					 Vector<String> user_id = (Vector<String>) chattingVO.getObj();
					 
					 Iterator<String> iter = chatServer.is.getServer().getClients().keySet().iterator();
					 while(iter.hasNext()){
						 String key = iter.next();
						 for(int i = 0; i< user_id.size(); i++){
							 if(key.equals(user_id.get(i))){
								 chatServer.is.getServer().getClients().get(key).getOos().writeObject(ssvo);
								 break;
							 }
						 }
					 }
					break;
				}
				}	
			} catch (Exception ex) {

		}
	
	}		

	private Vector<String> name_setting(){
		Vector<String> v = new Vector<String>();
		Iterator<String> iter = chatServer.hash_id_name.keySet().iterator();
		while(iter.hasNext()){	// 리스트에 뿌려줄 아이디를 저장 및 백터로 변한
			String key = iter.next();
			v.add(chatServer.hash_id_name.get(key));
			System.out.println("리스트에 뿌려지는 해쉬맵 값을 뿌림. " + chatServer.hash_id_name.get(key));
		}
		return v;
	
	}
	// < 5. sendMsgAll 메소드 > 메시지를 모두 송출함.
	private void sendMsgAll(ChattingVO chattingVO) throws Exception { // 5-1. 부른 곳에서 예외처리를 해준다.
		Collection<ChatServerThread> col = chatServer.hash_chatter.values(); // 5-2. clients의 해시맵의 value값을 <ServerThread>형태의 collection(object그룹의z 값을 대표) 값으로 받는다.
		for (ChatServerThread st : col) { // 5-3. 콜렉션 값을 서버쓰레드로 하나씩(st) 받아오고,
			st.oos.writeObject(chattingVO); // 5-4. 데이터를 서버쓰레드의 ObjectOutputStream으로
									// 쓰고(입력하고)
			st.oos.flush(); // 5-5. 입력이 끝난 후 flush(초기화)시킨다.

		}
	}

}
